// Copyright (c) 2005  INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of cgal-python; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; version 2.1 of the License.
// See the file LICENSE.LGPL distributed with cgal-python.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $Id: Py_convex_hull_2.cpp 167 2007-11-02 15:36:54Z spion $
// $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal-python/trunk/cgal-python/bindings/Convex_hull_2/Py_convex_hull_2.cpp $
//
// Author(s)     : Naceur Meskini
//=========================================================================
#include <CGAL/basic.h>
#include <include/Kernels.h>
#include <CGAL/convex_hull_2.h>

#include <boost/python.hpp>
#include <boost/cstdint.hpp>
#include <include/iterator.h>

// include ====================================================================

using namespace boost::python;

template < class kernel> 
boost::python::list py_convex_hull_2(boost::python::list pts)
{
	typedef typename kernel::Point_2 Point_2;
	std::list<Point_2> In_list;
	std::list<Point_2> Out_list;
	
	boost::python::list result;

	for(int i = 0 ; i < pts.attr("__len__")() ; i++)
	{
		In_list.push_back(boost::python::extract<Point_2>(pts[i])); 
	}
	convex_hull_2(In_list.begin(),In_list.end(),std::back_inserter(Out_list));
	typename std::list<Point_2>::iterator iter;
	for(iter = Out_list.begin() ; iter != Out_list.end() ; ++iter) result.append(*iter);
	return result;
}

template < class kernel> 
boost::python::list py_ch_akl_toussaint(boost::python::list pts)
{
	typedef typename kernel::Point_2 Point_2;
	std::list<Point_2> In_list;
	std::list<Point_2> Out_list;
	
	boost::python::list result;

	for(int i = 0 ; i < pts.attr("__len__")() ; i++)
	{
		In_list.push_back(boost::python::extract<Point_2>(pts[i])); 
	}	  	
	ch_akl_toussaint(In_list.begin(),In_list.end(),std::back_inserter(Out_list));
	typename std::list<Point_2>::iterator iter;
	for(iter = Out_list.begin() ; iter != Out_list.end() ; ++iter) result.append(*iter);
	return result;
}
template < typename kernel> 
boost::python::list py_ch_graham_andrew(boost::python::list pts)
{
	typedef typename kernel::Point_2 Point_2;
	std::list<Point_2> In_list;
	std::list<Point_2> Out_list;
	
	boost::python::list result;

	for(int i = 0 ; i < pts.attr("__len__")() ; i++)
	{
		In_list.push_back(boost::python::extract<Point_2>(pts[i])); 
	}	  	
	ch_graham_andrew(In_list.begin(),In_list.end(),std::back_inserter(Out_list));
	typename std::list<Point_2>::iterator iter;
	for(iter = Out_list.begin() ; iter != Out_list.end() ; ++iter) result.append(*iter);
	return result;
}

template <class kernel > 
void Py_convex_hull_2()
{
	typedef typename kernel::Point_2 					Point_2;
	typedef typename std::list<Point_2>::iterator  		OutputItPoints;


const char * convex_hull_2_doc ="The function convex_hull_2 generates the counterclockwise sequence of extreme points from a given set of input points.\n\n"\
"convex_hull_2(self,list l) -> list of extreme points\n";

	def("convex_hull_2",&py_convex_hull_2<kernel>,convex_hull_2_doc);
	def("ch_akl_toussaint",&py_ch_akl_toussaint<kernel>,"a variant of convex_hull_2\n");
	def("ch_graham_andrew",&py_ch_graham_andrew<kernel>,"a variant of convex_hull_2\n");
}

void export_convex_hull_2()
{
	Py_convex_hull_2<K>();
}
